package com.util.mapdemo;

import java.util.*;

/**
 * @Author:zxh
 * @Description: enumMap, enumSet的练习
 * @Date: 2020/10/29
 * @Modified By:
 */
public class EnumMapDemo {
    //1.它们不会抛出ConcurrentModificationException ，并且它们可能显示或可能不显示在迭代进行时发生的映射的任何修改的影响
    //2.不允许使用空键。 尝试插入空键将丢失NullPointerException 。 然而，尝试测试是否存在空键或删除一个将会正常工作。 允许空值
    //3.像大多数集合实现一样， EnumMap不同步。 如果多个线程同时访问枚举映射，并且至少有一个线程修改映射，则应该在外部进行同步
    //4.使用Collections.synchronizedMap(java.util.Map<K, V>)方法“包装”地图。 这最好在创建时完成，以防止意外的不同步访问：
    // Map<EnumKey, V> m  = Collections.synchronizedMap(new EnumMap<EnumKey, V>(...));

    public enum Color {
        RED, BLACK, WHITE, GREEN
    }

    /**
     * enumMapDemo
     */
    public void enumMapDemo() {
        //它没有空构造，必须制定枚举class类型。当然构造函数也可以接收一个Mapnew EnumMap<>(EnumMap/Map);
        Map<Color, String> map = new EnumMap<Color, String>(Color.class);
        map.put(Color.RED, "红色");
        map.put(Color.WHITE, "白色");
        map.put(Color.WHITE, "白色");
        map.put(Color.BLACK, "黑色");
        //遍历：发现EnumMap它的存储是有序的
        map.forEach((color, v) -> System.out.println("color:" + color + " v:" + v));

        //可以看到，它并不会发生并发修改异常ConcurrentModificationException
        map.forEach((key, value) -> {
            if (key == Color.WHITE) {
                map.put(Color.GREEN, "绿色");
            }
            System.out.println("key:" + key + "  value:" + value);
        });

        //key不允许为null  todo java.lang.NullPointerException
        map.put(null, "null");
    }

    /**
     * EnumMap还有一种用法是被继承
     */
    public class ColorMap extends EnumMap<Color, String> {
        public ColorMap() {
            super(Color.class);
        }
    }

    public void ColorMapDemo() {
        Map<Color, String> colorMap = new ColorMap();
        colorMap.put(Color.BLACK, "黑色");
        System.out.println(colorMap.get(Color.BLACK));
        //Collections
    }


    /******************************************enumSet **********************************************/
    /**
     * EnumSet是个抽象类，所以构建它只能通过static方法。它通过内建的实现类RegularEnumSet来保证高效率
     */
    public void enumSetDemo() {
        EnumSet<Color> colors = EnumSet.allOf(Color.class);
        System.out.println("colors:" + colors);

        colors = EnumSet.noneOf(Color.class);
        System.out.println("noneOf:" + colors);
        // 添加元素
        colors.add(Color.BLACK);
        colors.add(Color.WHITE);
        System.out.println("add: " + colors);

        //自己人工指定
        colors = EnumSet.of(Color.RED, Color.BLACK, Color.GREEN, Color.RED);
        System.out.println("of:" + colors);

        // 根据区间来创建
        colors.clear();
        //colors = EnumSet.range(Color.BLACK,Color.RED);
        colors = EnumSet.range(Color.WHITE, Color.GREEN);
        System.out.println("range: " + colors);

        // 相当于取差集的意思~
        System.out.println("complementOf: " + EnumSet.complementOf(colors));

        // copyOf方法克隆一个（请注意是克隆，并不是返回的一个视图）
        System.out.println("copyOF: " + EnumSet.copyOf(colors));
    }

    public void enumSetTwo() {
        EnumSet<Color> colors = EnumSet.of(Color.RED, Color.BLACK);
        EnumSet<Color> es = EnumSet.of(Color.WHITE);
        System.out.println("es: " + es);
        es.addAll(colors);
        System.out.println("addAll: " + es);
        es.clone();
        System.out.println("clone: " + es);
    }

    public static void main(String[] args) {
        // new EnumMapDemo().enumMapDemo();
        // new EnumMapDemo().ColorMapDemo();
        // new EnumMapDemo().enumSetDemo();
        new EnumMapDemo().enumSetTwo();

    }


    //泛型的熟悉
    public class ClassTo<T> {
        public native ClassTo<? super T> getSuperclass();
    }

    //transient
    private transient Object[] vals;


}
